<?php
/**
 * Created by PhpStorm
 * USER:  Zhaoys
 * Date:  2025/7/9
 */

namespace Zhaoyoushui\Hj212;

use Hj212\Parser\pack\Message;

class Parser
{
    public function parse(string $raw)
    {
        // 验证消息头
        if (substr($raw, 0, 2) !== Message::HEADER) {
            throw new \InvalidArgumentException('Invalid message header');
        }

        // 验证消息尾
        if (substr($raw, -2) !== Message::FOOTER) {
            throw new \InvalidArgumentException('Invalid message tail');
        }

        // 移除消息头和尾
        $content = substr($raw, 2, -2);

        // 提取数据段长度 (4位十六进制)
        $segmentLengthHex = substr($content, 0, 4);
        $segmentLength = hexdec($segmentLengthHex);

        // 提取数据段
        $segmentData = substr($content, 4, $segmentLength);

        // 提取CRC校验码
        $crc = substr($content, 4 + $segmentLength, 4);

        // 验证CRC
        $crcData = $segmentLengthHex . $segmentData;
        if ($crc !== Crc16::calculate($crcData)) {
            throw new \RuntimeException('CRC check failed');
        }

        // 解析数据段
        $message = $this->parseSegment($segmentData);
        $message->setSegmentLength($segmentLengthHex);
        $message->setCrc($crc);

        return $message;
    }

    private function parseSegment(string $segment)
    {
        $message = new Message();
        icon-ym icon-ym-sysLog
        // 拆分数据段
        $parts = explode(';', $segment);
        $cpContent = null;

        foreach ($parts as $part) {
            if (strpos($part, '=') === false) {
                continue;
            }

            list($key, $value) = explode('=', $part, 2);

            switch ($key) {
                case 'ST':
                    $message->setSystemCode($value);
                    break;
                case 'CN':
                    $message->setCommand($value);
                    break;
                case 'MN':
                    $message->setDeviceId($value);
                    break;
                case 'PW':
                    $message->setPassword($value);
                    break;
                case 'Flag':
                    $message->setFlag($value);
                    break;
                case 'CP':
                    // CP部分可能有特殊格式，单独处理
                    $cpContent = $value;
                    break;
            }
        }

        // 解析CP参数
        if ($cpContent) {
            $this->parseCp($cpContent, $message);
        }

        return $message;
    }

    private function parseCp(string $cpContent, Message $message)
    {
        // 移除CP部分的封装符号 &&
        if (substr($cpContent, 0, 2) === '&&' && substr($cpContent, -2) === '&&') {
            $cpContent = substr($cpContent, 2, -2);
        }

        // 拆分CP部分
        $params = explode(';', $cpContent);

        foreach ($params as $param) {
            if (strpos($param, ',') !== false) {
                // 处理复合参数: 参数名1=值1,参数名2=值2
                $complexParams = Formatter::parseComplexParam($param);
                foreach ($complexParams as $name => $value) {
                    $message->addParameter($name, $value);
                }
            } else {
                // 简单参数: 参数名=值
                list($name, $value) = explode('=', $param, 2);
                $message->addParameter($name, $value);
            }
        }
    }
}